Skip to content

fix(cast): decode replay blocks with AnyNetwork - #16459

Merged
mattsse merged 2 commits into
masterfrom
mattsse/cast-run-any-network
Aug 29, 2026
Merged

fix(cast): decode replay blocks with AnyNetwork#16459
mattsse merged 2 commits into
masterfrom
mattsse/cast-run-any-network

Conversation

@mattsse

@mattsse mattsse commented Aug 29, 2026

Copy link
Copy Markdown
Member

cast run built its provider from FEN::Network, which outside Optimism, Tempo and Monad is the strict Ethereum network. One transaction that envelope cannot decode fails the whole block:

Error: deserialization error: data did not match any variant of untagged enum BlockTransactions

Arbitrum puts its internal transaction (type 0x6a) at index 0 of every block, so no Arbitrum transaction has ever been replayable — --quick included, and as far back as I looked. Celo (0x7b) and the OP-stack forks Foundry does not route to the Optimism network, such as Mantle and Berachain (0x7e), fail the same way. cast tx and cast block --full were never affected because they already use AnyNetwork.

RPC now decodes with AnyNetwork and transactions convert through FromAnyRpcTransaction, which the fork backend already relies on for exactly this reason. Two details fall out of that. Transactions are classified as system transactions before being decoded, since the envelopes a chain reserves for itself are precisely the ones this build may not decode. And Monad keeps a typed provider for its block context, which is defined over FEN::Network.

Moving Optimism onto the same path surfaced a second bug: FromAnyRpcTransaction for OpTx left enveloped_tx empty, and op-revm rejects a non-deposit transaction without it, since the L1 data fee is charged off those bytes. It now carries the 2718 encoding.

Verified against live nodes. Arbitrum transactions replay and match receipt gas exactly once gasUsedForL1 is subtracted — 216899 on-chain, 273 of it L1, 216626 locally. Ethereum, Optimism and Base still match receipt gas exactly.

Arbitrum needs #16457 as well to replay end to end; without it the block decodes and then stops on MissingParentBeaconBlockRoot. The two are independent and touch different hunks. Celo's 0x7b fee-currency transactions still cannot be converted — that needs Celo-specific handling and is out of scope here, though Celo's standard transactions now work.


This PR was written by Claude Code, including the investigation behind it and this description. Verified against live nodes for each chain named above.

`cast run` built its provider from `FEN::Network`, which for every chain
outside Optimism, Tempo and Monad is the strict Ethereum network. A block
containing a transaction type that envelope cannot decode failed to
deserialize as a whole:

    Error: deserialization error: data did not match any variant of
    untagged enum BlockTransactions

Arbitrum puts its internal transaction (type `0x6a`) at index 0 of every
block, so no Arbitrum transaction has ever been replayable. Celo (`0x7b`)
and OP-stack forks Foundry does not route to the Optimism network, such
as Mantle and Berachain (`0x7e`), fail the same way. `cast tx` and
`cast block --full` already use `AnyNetwork` and were unaffected.

RPC now uses `AnyNetwork` and transactions convert through
`FromAnyRpcTransaction`, which execution already relies on in the fork
backend. Transactions are classified as system transactions before being
decoded, since a chain's reserved envelopes are exactly the ones this
build may not decode, and Monad keeps a typed provider for its block
context.

`FromAnyRpcTransaction for OpTx` left `enveloped_tx` empty, which op-revm
rejects for non-deposit transactions because the L1 data fee is charged
off those bytes. It now carries the 2718 encoding, which keeps Optimism
and Base exact through the new path.

Verified against live nodes: Arbitrum transactions replay and match
receipt gas exactly once `gasUsedForL1` is subtracted, and Ethereum,
Optimism and Base still match receipt gas exactly.
@github-actions

Copy link
Copy Markdown
Contributor

✅ Changelog found

The deterministic check will validate the changed entry.

figtracer
figtracer previously approved these changes Aug 29, 2026
@mattsse
mattsse merged commit 69370a3 into master Aug 29, 2026
27 checks passed
@mattsse
mattsse deleted the mattsse/cast-run-any-network branch August 29, 2026 08:31
@github-project-automation github-project-automation Bot moved this to Done in Foundry Aug 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants